home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.4d7 source / tn3270 / writescr.c < prev    next >
Text File  |  1992-04-17  |  36KB  |  1,469 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.4d7  April, 1992
  5.  *  Copyright (c) 1988, 1989, 1990, 1991, 1992 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #if !defined(USEDUMP)
  34.     #include "maclib.h"
  35.     #include "termdef.h"
  36.     #include "tn3270funcs.h"
  37.     #include "globals.h"
  38. #else
  39.     #pragma load "tn3270DumpFile"
  40. #endif
  41.  
  42. #pragma segment 3270seg1
  43.  
  44. extern RGBColor realblack;
  45. extern RGBColor realwhite;
  46.  
  47. void invldscr(cnr *cp)
  48. {
  49. GrafPtr gp;
  50.  
  51. if (sw_bgrnd) {
  52.     sw_upd = 1;
  53.     return;
  54.     }
  55. if (cp->myWindow == 0) return; 
  56.  
  57. cp->needwrite = 1;
  58. GetPort(&gp);
  59. SetPort(cp->myWindow);
  60. InvalRect(&(cp->textRect));
  61. SetPort(gp);
  62. checkpos(cp);
  63. }
  64.  
  65. void checkpos(cnr *cp)
  66. {
  67. if (cp->myWindow == 0) return;
  68. if (!(cp->cs.curpos)) return;
  69. cp->statcpos = 1;
  70. newstat(cp);
  71. cp->statcpos = 0;
  72. }
  73.  
  74. void writescr(char printflag, cnr *cp)
  75. {
  76. register unsigned short a, i, cattr, fattr, start, count;
  77. unsigned short offset, lastfield;
  78. char geflg, g;
  79. static unsigned long * Ticks = (unsigned long *)0x16a;
  80. unsigned long stasklim;
  81.  
  82.  
  83. if (cp->myWindow == 0) return;
  84.  
  85. /* get field attribute for first screen position, even if it */
  86. /* is defined by a subsequent field wrapping to the start.   */
  87. fattr = lastfield = 0;
  88. if (cp->fmtscrn) {
  89.     if ((cp->atrbuff)[0] & 0x8000) {
  90.         lastfield = (cp->atrbuff)[0] & 0x3fdf;
  91.         fattr = lastfield & 0x3f1f;
  92.         }
  93.     else for (i = cp->maxoff; i > 0; i--)
  94.         if ((cp->atrbuff)[i] & 0x8000) {
  95.             lastfield = (cp->atrbuff)[i] & 0x3fdf;
  96.             fattr = lastfield & 0x3f1f;
  97.             break;
  98.             }
  99.     }
  100.  
  101. cp->WriteCurr = 0;
  102. if (printflag == 0) EraseRect(&(cp->textRect));
  103. cp->framedfield = 0;
  104. cattr = fattr;
  105. if (cp->tcpflg) stasklim = (*Ticks) + 4;
  106. for (start = 0; start < cp->maxcnt; start += cp->scrhsize) {
  107.     if (cp->tcpflg) {
  108.         if ((*Ticks) > stasklim) {
  109.             myStask();
  110.             stasklim = (*Ticks) + 4;
  111.             }
  112.         }
  113.     count = 0;
  114.     geflg = 0;
  115.     offset = start;
  116.     MoveTo(cp->htxtstrt, cp->WriteCurr*cp->vtxtsize + cp->vtxtstrt);
  117.     for (i=0; i < cp->scrhsize; i++) {
  118.         a = (cp->atrbuff)[start+i];
  119.         g = (a & 0x40c0) != 0;
  120.         a &= 0xbfff;
  121.         if (a & 0x8000) {
  122.             dfield(offset, count, lastfield, cattr, geflg, cp);
  123.             /* attribute byte is a field by itself */
  124.             offset = start + i;
  125.             count = -1;        /* indicates attribute byte */
  126.             fattr = a & 0x3fff;
  127.             dfield(offset, count, fattr, fattr, 0, cp);
  128.             lastfield = fattr & 0x3fdf;    /* selection doesn't propagate */
  129.             fattr = lastfield & 0x3f1f;
  130.             cattr = fattr;
  131.             count = 0;
  132.             geflg = 0;
  133.             offset = start + i + 1;
  134.             }
  135.         else {
  136.             a &= 0x3f3f;
  137.             if ((a == 0) && (cattr == fattr)) {
  138.                 count++;
  139.                 geflg |= g;
  140.                 continue;
  141.                 }
  142.             if (a == cattr) {
  143.                 count++;
  144.                 geflg |= g;
  145.                 continue;
  146.                 }
  147.             /* else start new field */
  148.             dfield(offset, count, lastfield, cattr, geflg, cp);
  149.             count = 1;
  150.             offset = start + i;
  151.             cattr = a;
  152.             geflg = g;
  153.             }
  154.         }
  155.     dfield(offset, count, lastfield, cattr, geflg, cp);
  156.     cp->WriteCurr ++;
  157.     }
  158.  
  159. if (printflag) return;
  160. cp->x = cp->curadr%cp->scrhsize;
  161. cp->y = cp->curadr/cp->scrhsize;
  162. defcursor(cp->x, cp->y, cp);        /* define er rectangle for cursor */
  163. if (!(cp->textmap)) drawcurs(0, cp);
  164. }
  165.  
  166. void newcur(cnr *cp)
  167. {
  168. GrafPtr gp;
  169.  
  170. if (sw_bgrnd) {
  171.     sw_upd = 1;
  172.     return;
  173.     }
  174. if (cp->myWindow == 0) return;
  175.  
  176. GetPort(&gp);
  177. SetPort(cp->myWindow);
  178. if (cp->textmap) InvalRect(&(cp->er));
  179. else drawcurs(1, cp);
  180. cp->x = cp->curadr%cp->scrhsize;
  181. cp->y = cp->curadr/cp->scrhsize;
  182. defcursor(cp->x, cp->y, cp);        /* define er rectangle for cursor */
  183. if (cp->textmap) InvalRect(&(cp->er));
  184. else drawcurs(0, cp);
  185. SetPort(gp);
  186. checkpos(cp);
  187. }
  188.  
  189. void newchar(short offset, unsigned char value,
  190.              short atr, short fattr, cnr *cp)
  191. {
  192. short newatr, selattr;
  193.  
  194. (cp->chrbuff)[offset] = value;
  195. if (cp->cutflag) {                /* allow deletion of selection attribute */
  196.     (cp->atrbuff)[offset] = atr;
  197.     }
  198. else {                        /* preserve selection attribute */
  199.     selattr = (cp->atrbuff)[offset] & 0x0020;
  200.     (cp->atrbuff)[offset] = (atr & 0xffdf) | selattr;
  201.     }
  202.  
  203. if (sw_bgrnd) {
  204.     sw_upd = 1;
  205.     return;
  206.     }
  207. if (cp->myWindow == 0) return;
  208.  
  209. newatr = fattr & 0x3fff;
  210. /* if (atr & 0x4000) newatr |= 0x4000; */
  211.  
  212. if (cp->in_len == 0) {
  213.     cp->in_len = 1;
  214.     cp->in_off = offset;
  215.     cp->in_atr = newatr;
  216.     return;
  217.     }
  218.  
  219. if ( (cp->in_atr != newatr) || (cp->in_off/cp->scrhsize != offset/cp->scrhsize) ||
  220.      (offset-cp->in_off-cp->in_len > 0) || (cp->in_off-offset > 1) ) {
  221.         dchar(cp->in_off, cp->in_len, cp->in_atr, cp);
  222.         cp->in_len = 1;
  223.         cp->in_off = offset;
  224.         cp->in_atr = newatr;
  225.         return;
  226.         }
  227.  
  228. if ((cp->in_off+cp->in_len) == offset) {
  229.     cp->in_len++;
  230.     return;
  231.     }
  232. if (cp->in_off-offset == 1) {
  233.     cp->in_len++;
  234.     cp->in_off--;
  235.     }
  236. }
  237.  
  238. void dchar(short offset, short len, short fattr, cnr *cp)
  239. {
  240. short i, selattr, dstart, dlen;
  241.  
  242. if (len < 1) return;
  243. if (len == 1) {
  244.     seldchar(offset, len, (cp->atrbuff)[offset] & 0x3f3f, fattr, cp);
  245.     return;
  246.     }
  247. selattr = (cp->atrbuff)[offset] & 0x3f3f;
  248. dstart = offset;
  249. dlen = 1;
  250. for (i=1; i < len; i++)
  251.     if (((cp->atrbuff)[offset+i] & 0x3f3f) != selattr) {
  252.         seldchar(dstart, dlen, selattr, fattr, cp);
  253.         selattr = (cp->atrbuff)[offset+i] & 0x3f3f;
  254.         dstart = offset+i;
  255.         dlen = 1;
  256.         }
  257.     else dlen++;
  258.     
  259. seldchar(dstart, dlen, selattr, fattr, cp);
  260. }
  261.  
  262. void seldchar(short offset, short len, short selattr, short fattr, cnr *cp)
  263. {
  264. Rect r;
  265. register short x, y;
  266. GrafPtr gp;
  267. unsigned char attrbits;
  268. RGBColor rgbtemp;
  269. short chrtop;
  270. char prot, fieldfont;
  271.  
  272. prot = (fattr & 0x2000) != 0;
  273. fieldfont = (fattr & 0x00c0) >> 6;
  274. fattr &= 0xff3f;
  275. getdspatr(&attrbits, 0L, &rgbtemp, selattr, fattr, cp);
  276.  
  277. GetPort(&gp);
  278. SetPort(cp->WritePtr);
  279. if (cp->textmap) setgdev(cp);
  280. y = offset/cp->scrhsize;
  281. x = offset%cp->scrhsize;
  282. chrtop = r.top = y*cp->vtxtsize;
  283. if (cp->htxtstrt == 0) r.top--;        /* adjust for 12-point */
  284. r.left = cp->htxtstrt+x*cp->htxtsize;
  285. r.bottom = r.top+cp->vtxtsize;
  286. r.right = r.left + len * cp->htxtsize;
  287. if (!(cp->textmap))
  288.     if ((cp->curadr >= offset) && (cp->curadr < offset+len)) drawcurs(1, cp);
  289. if (cp->framedfield) {        /* adjust to not erase any frames on screen */
  290.     r.bottom--;
  291.     }
  292. if (colormac && (!cp->cs.nocolor))
  293.     if (attrbits & 0x20) {            /* reversed field */
  294.         RGBBackColor(&rgbtemp);
  295.         if (cp->cs.invertbw) GetEntryColor(cp->myPalette, RGBwhite, &rgbtemp);
  296.                   else GetEntryColor(cp->myPalette, RGBblack, &rgbtemp);
  297.         RGBForeColor(&rgbtemp);
  298.         }
  299.     else RGBForeColor(&rgbtemp);    /* normal field */
  300. EraseRect(&r);
  301. if (!(attrbits & 0x80)) {        /* displayable */
  302.     MoveTo(r.left, cp->vtxtstrt+chrtop);
  303.     txtfield(offset, len, attrbits, prot, fieldfont, cp);
  304.  
  305. /*    if (fattr & 0x4000) fnum = APLFONT;
  306.                    else fnum = cp->stdfont;
  307.     if (attrbits & 0x08) fnum += 2;
  308.     if (fnum != cp->stdfont) TextFont(fnum);
  309.     myDrawText(cp->chrbuff, offset, len, fnum, prot, cp);
  310.     if (fnum != cp->stdfont) TextFont(cp->stdfont); */
  311.  
  312.     if (attrbits & 0x10) {
  313.         MoveTo(r.left, chrtop+cp->vtxtstrt+(cp->curvsize>>2)-3);
  314.         LineTo(r.right+1, chrtop+cp->vtxtstrt+(cp->curvsize>>2)-3);
  315.         }
  316.     if (((!colormac) || (cp->cs.nocolor)) && (attrbits & 0x20)) InvertRect(&r);
  317.     }
  318. if (colormac && (!cp->cs.nocolor) && (attrbits & 0x20)) {
  319.     GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  320.     RGBBackColor(&rgbtemp);
  321.     }
  322. SetPort(cp->myWindow);
  323. if (cp->textmap) {
  324.     resetgdev();
  325.     if (r.top < cp->inrect.top) cp->inrect.top = r.top;
  326.     if (r.left < cp->inrect.left) cp->inrect.left = r.left;
  327.     if (r.bottom > cp->inrect.bottom) cp->inrect.bottom = r.bottom;
  328.     if (r.right > cp->inrect.right) cp->inrect.right = r.right;
  329.     }
  330. else if ((cp->curadr >= offset) && (cp->curadr < offset+len)) drawcurs(0, cp);
  331. SetPort(gp);
  332. }
  333.  
  334. void newwrite(cnr *cp)
  335. {
  336. GrafPtr gp;
  337.  
  338. if (sw_bgrnd) return;
  339. if (cp->myWindow == 0) return;
  340.  
  341. if (cp->in_len > 0) {
  342.     dchar(cp->in_off, cp->in_len, cp->in_atr, cp);
  343.     cp->in_len = 0;
  344.     }
  345.  
  346. if (!(cp->textmap)) return;
  347. GetPort(&gp);
  348. SetPort(cp->myWindow);
  349. if (cp->inrect.top <= cp->inrect.bottom) {
  350.     InvalRect(&(cp->inrect));
  351.     }
  352. cp->inrect.top = cp->inrect.left = 32767;
  353. cp->inrect.bottom = cp->inrect.right = -32767;
  354. SetPort(gp);
  355. }
  356.  
  357. void dfield(short offset, short count, short fattr, short cattr,
  358.             char g, cnr *cp)
  359. {
  360. struct Rect z;
  361. unsigned char attrbits, trim;
  362. short xend, yend, txtcount, txtoff, adjcount, adjoff;
  363. RGBColor rgbfield, rgbrev;
  364. char prot, fieldfont;
  365. short fnum;
  366.  
  367. if (count == 0) return;
  368.  
  369. fieldfont = (fattr & 0x00c0) >> 6;
  370. fattr &= 0xff3f;
  371.  
  372. /* get attribute definition for this field */
  373. prot = (fattr & 0x2000) != 0;
  374. trim = 1;
  375. getdspatr(&attrbits, &trim, &rgbfield, cattr, fattr, cp);
  376. if (count == -1) {
  377.     attrbits = cp->cs.attrmap[6];
  378.     trim = 0;
  379.     count = 1;
  380.     if (cattr & 0x0020) {
  381.         attrbits &= 0x8f;
  382.         attrbits |= 0x20;
  383.         }
  384.     }
  385.  
  386. /* remember where to end up when done */
  387. xend = cp->htxtstrt + (offset%cp->scrhsize)*cp->htxtsize + count*cp->htxtsize;
  388. yend = cp->WriteCurr*cp->vtxtsize + cp->vtxtstrt;
  389.  
  390. /* if appropriate, calculate new count and offset to eliminate leading
  391.    and trailing blanks and nulls  */
  392. adjcount = txtcount = count;
  393. adjoff = txtoff = offset;
  394. calctrim(&txtoff, &txtcount, cp);    /* don't draw blanks and nulls */
  395. if (!(fattr & 0x2000)) trim = 0;    /* unprotected not trimmed */
  396. if (trim) {
  397.     adjcount = txtcount;
  398.     adjoff = txtoff;
  399.     }
  400.  
  401. /* define nominal rectangle for this update */
  402. z.top = cp->WriteCurr * cp->vtxtsize;
  403. z.bottom = z.top + cp->vtxtsize;
  404. if (cp->htxtstrt == 0) {    /* adjust for 12-point */
  405.     z.top--;
  406.     z.bottom--;
  407.     }
  408. z.left = cp->htxtstrt + (adjoff%cp->scrhsize) * cp->htxtsize;
  409. z.right =  z.left + adjcount * cp->htxtsize;
  410.  
  411. /* define colors for normal or reversed field */
  412. if (colormac && (!cp->cs.nocolor))
  413.     if (attrbits & 0x20) {
  414.         RGBBackColor(&rgbfield);
  415.         if (adjcount > 0) {
  416.             if (attrbits & 0x40) {
  417.                 z.left -= 1;
  418.                 z.right += 1 - cp->htxtstrt;
  419.                 }
  420.             EraseRect(&z);
  421.             if (attrbits & 0x40) {
  422.                 z.left += 1;
  423.                 z.right -= 1 - cp->htxtstrt;
  424.                 }
  425.             }
  426.         GetEntryColor(cp->myPalette, RGBback, &rgbrev);
  427.         RGBBackColor(&rgbrev);
  428.         if (cp->cs.invertbw) GetEntryColor(cp->myPalette, RGBwhite, &rgbrev);
  429.                   else GetEntryColor(cp->myPalette, RGBblack, &rgbrev);
  430.         RGBForeColor(&rgbrev);
  431.         }
  432.     else RGBForeColor(&rgbfield);
  433.  
  434. /* draw text if not non-display or all blanks or nulls */
  435. if (txtoff != offset) MoveTo(cp->htxtstrt+(txtoff%cp->scrhsize)*cp->htxtsize, yend);
  436. if (!((attrbits & 0x80) || (txtcount == 0)))
  437.     if (g) {
  438.         txtfield(txtoff, txtcount, attrbits, prot, fieldfont, cp);
  439.         }
  440.      else {
  441.         if (fieldfont == 1) fnum = APLFONT;
  442.         else fnum = cp->stdfont;
  443.         if (attrbits & 0x08) fnum += 2;
  444.         if (fnum != cp->stdfont) TextFont(fnum);
  445.          myDrawText(cp->chrbuff, txtoff, txtcount, fnum, prot, cp);
  446.         if (fnum != cp->stdfont) TextFont(cp->stdfont);
  447.         }
  448. MoveTo(xend, yend);
  449.  
  450. /* return if no other attributes */
  451. if (!(attrbits & 0x70)) return;
  452.  
  453. /* return if trimming has removed field */
  454. if (adjcount == 0) return;
  455.  
  456. /* frame if requested */
  457. if (attrbits & 0x40) {
  458.     z.top -= 1;
  459.     z.left -= 2;
  460.     z.right += 2 - cp->htxtstrt; 
  461.     if (colormac && (!cp->cs.nocolor)) RGBForeColor(&rgbfield);
  462.     FrameRect(&z);
  463.     z.top += 1;
  464.     z.bottom -= 1;
  465.     z.left += 1;
  466.     z.right -= 1;
  467.     cp->framedfield = 1;
  468.     }
  469.  
  470. /* underline if requested */
  471. if (attrbits & 0x10) {
  472.     if (colormac && (!cp->cs.nocolor))
  473.         if (attrbits & 0x20) RGBForeColor(&rgbrev);
  474.                         else RGBForeColor(&rgbfield);
  475.     MoveTo(z.left, yend+(cp->curvsize>>2)-3);
  476.     LineTo(z.right-1, yend+(cp->curvsize>>2)-3);
  477.     }
  478.  
  479. /* reverse if requested */
  480. if (((!colormac) || (cp->cs.nocolor)) && (attrbits & 0x20)) InvertRect(&z);
  481.  
  482. /* leave pen ready for next character */
  483. MoveTo(xend, yend);
  484. }
  485.  
  486. void calctrim(short *offset, short *count, cnr *cp)
  487. {
  488. register short adjoff, adjcount, i, j, k;
  489.  
  490. adjcount = j = (*count);
  491. adjoff = k = (*offset);
  492. for (i = 0; i < j; i++) {
  493.     if (((cp->chrbuff)[k] == 0x40) || ((cp->chrbuff)[k] == 0x00)) {
  494.         adjoff++;
  495.         adjcount--;
  496.         }
  497.     else break;
  498.     k++;
  499.     }
  500. j = adjcount;
  501. k = adjoff + adjcount - 1;
  502. for (i = 0; i < j; i++) {
  503.     if (((cp->chrbuff)[k] == 0x40) || ((cp->chrbuff)[k] == 0x00)) adjcount--;
  504.     else break;
  505.     k--;
  506.     }
  507. (*offset) = adjoff;
  508. (*count) = adjcount;
  509. }
  510.  
  511. void getdspatr(unsigned char *atr_result,
  512.                unsigned char *trim_result,
  513.                RGBColor *color_result,
  514.                register unsigned short cattr,
  515.                register unsigned short fattr,
  516.                cnr *cp)
  517. {
  518. register unsigned char attrbits;
  519. unsigned char exthi, color, trim, cnum;
  520. static RGBColor * HiliteRGB = (RGBColor *)0xda0;
  521.  
  522. if (trim_result != 0) trim = (*trim_result);
  523.  
  524. /* determine extended highlighting value to use */
  525. exthi = (cattr & 0x0018) >> 3;
  526. if (exthi == 0) exthi = (fattr & 0x0018) >> 3;
  527.  
  528. /* get default, highlight, or non-display attribute */
  529. switch ((fattr & 0x0C00) >> 10) {
  530.     case 0:
  531.     case 1: attrbits = cp->cs.attrmap[0];
  532.             break;
  533.     case 2: attrbits = cp->cs.attrmap[1];
  534.             break;
  535.     case 3: attrbits = cp->cs.attrmap[2];
  536.             exthi = 0;    /* non-display cancels ext. high */
  537.             trim = 0;
  538.             break;
  539.     default: attrbits = 0;
  540.             break;
  541.     }
  542.     
  543. /* add extended highlighting to basic attributes */
  544. switch (exthi) {
  545.     case 0: break;
  546.     case 1: attrbits |= cp->cs.attrmap[4];
  547.             break;
  548.     case 2: attrbits |= cp->cs.attrmap[3];
  549.             trim = 0;
  550.             break;
  551.     case 3: attrbits |= cp->cs.attrmap[5];
  552.             trim = 0;
  553.             break;
  554.     default: break;
  555.     }
  556.  
  557. /* adjust attrbits for mouse selection field */
  558. if (cattr & 0x0020) {
  559.     attrbits &= 0x8f;        /* cancel frame, reverse, underline */
  560.     attrbits |= 0x20;        /* set reverse bit */
  561.     trim = 0;                /* don't trim */
  562.     }
  563.  
  564. /* determine color value to use */
  565. if (colormac && (!cp->cs.nocolor)) {
  566.     if (cattr & 0x0020) {    /* use highlight color for selection text */
  567.         (*color_result) = (*HiliteRGB);
  568.         if ((((*color_result) == realblack) && (!(cp->cs.invertbw))) ||
  569.             (((*color_result) != realblack) && cp->cs.invertbw)) {
  570.             (*color_result).red = 0xffff - (*color_result).red;
  571.             (*color_result).green = 0xffff - (*color_result).green;
  572.             (*color_result).blue = 0xffff - (*color_result).blue;
  573.             }
  574.         }
  575.     else {
  576.         color = cattr & 0x0007;
  577.         if (color == 0) color = fattr & 0x0007;
  578.         if (color == 0) {
  579.              if (fattr & 0x2000) {    /* protected */
  580.                 if ((fattr & 0x0c00) == 0x0800) {    /* high-intensity */
  581.                     color = 7;                                     /* white */
  582.                     }
  583.                 else {
  584.                     if (cp->cs.basecolor || cp->colorfield) color = 4;    /* green */
  585.                     else color = 1;                                /* blue */
  586.                     }
  587.                 }    
  588.              else {                    /* unprotected */
  589.                 if ((fattr & 0x0c00) == 0x0800) {    /* high-intensity */
  590.                     if (cp->cs.basecolor || cp->colorfield) color = 7;    /* white */
  591.                     else color = 2;                                /* red */
  592.                     }
  593.                 else {
  594.                     color = 4;                                    /* green */
  595.                     }
  596.                 }
  597.             }
  598.         switch(color) {
  599.             case 1:    cnum = RGBblue;
  600.                     break;
  601.             case 2:    cnum = RGBred;
  602.                     break;
  603.             case 3: cnum = RGBpink;
  604.                     break;
  605.             case 5:    cnum = RGBturquoise;
  606.                     break;
  607.             case 6:    cnum = RGByellow;
  608.                     break;
  609.             case 7:    if (cp->cs.invertbw) cnum = RGBblack;
  610.                     else cnum = RGBwhite;
  611.                     break;
  612.             default: cnum = RGBgreen;
  613.                     break;
  614.             }
  615.         GetEntryColor(cp->myPalette, cnum, color_result);
  616.         }
  617.     }
  618. if (trim_result != 0) (*trim_result) = trim;
  619. (*atr_result) = attrbits;
  620. }
  621.  
  622.  
  623. void txtfield(short offset, short count, unsigned char attrbits,
  624.               char prot, char fieldfont, cnr *cp)
  625. {
  626. register short start, len, lim, f, i, fnum;
  627. register unsigned char font;
  628.  
  629. start = offset;
  630. len = 0;
  631. lim = offset + count;
  632. if ((cp->atrbuff)[offset] & 0x4000) {
  633.     font = 1;
  634.     }
  635. else {
  636.     font = ((cp->atrbuff)[offset] & 0x00c0) >> 6;
  637.     }
  638. if (font == 0) font = fieldfont;
  639. for (i=offset; i < lim; i++) {
  640.     if ((cp->atrbuff)[i] & 0x4000) {
  641.         f = 1;
  642.         }
  643.     else {
  644.         f = ((cp->atrbuff)[i] & 0x00c0) >> 6;
  645.         }
  646.     if (f == 0) f = fieldfont;
  647.     if (font == f) len++;
  648.     else {
  649.         if (font == 1) fnum = APLFONT;
  650.             else fnum = cp->stdfont;
  651.         if (attrbits & 0x08) fnum += 2;
  652.         TextFont(fnum);
  653.         myDrawText(cp->chrbuff, start, len, fnum, prot, cp);
  654.         font = f;
  655.         start = i;
  656.         len = 1;
  657.         }
  658.     }
  659. if (font == 1) fnum = APLFONT;
  660.     else fnum = cp->stdfont;
  661. if (attrbits & 0x08) fnum += 2;
  662. TextFont(fnum);
  663. myDrawText(cp->chrbuff, start, len, fnum, prot, cp);
  664. if (fnum != cp->stdfont) TextFont(cp->stdfont);
  665. }
  666.  
  667. void myDrawText(register unsigned char *textBuf,
  668.                 register short firstByte,
  669.                 register short byteCount,
  670.                 short font, char prot, cnr *cp)
  671. {
  672. register short i, j;
  673.  
  674. if (byteCount <= 0) return;
  675.  
  676. if (cp->nl_handle == 0) {    /* no translation */
  677.     if (((font == ALAFONT) || (font == BOLDALA)) && prot && (!(cp->plainala))) {
  678.         ALADrawText(textBuf, firstByte, byteCount);
  679.         }
  680.     else {
  681.         DrawText(textBuf, firstByte, byteCount);
  682.         }
  683.     return;
  684.     }
  685.  
  686. if ((font == cp->stdfont) || (font == (cp->stdfont+2))) {
  687.     j = firstByte;
  688.     for (i=0; i < byteCount; i++) {
  689.         (cp->nlbuff)[i] = (cp->nltab)[textBuf[j++]];
  690.         }
  691.     DrawText(cp->nlbuff, 0, byteCount);
  692.     }
  693. else { /* translation does not apply to APL */
  694.     DrawText(textBuf, firstByte, byteCount);
  695.     }
  696. }
  697.  
  698. void ALADrawText(unsigned char *textBuf,
  699.                  short firstByte, short byteCount)
  700. {
  701. register unsigned char *sptr;
  702. register short i, textlen, state;
  703. unsigned char *textptr;
  704. short blankcount;
  705.  
  706. sptr = textBuf+firstByte;
  707. blankcount = textlen = 0;
  708. textptr = sptr;
  709. state = 0;
  710. for (i=firstByte; i < firstByte+byteCount; i++) {
  711.     switch(alatype(sptr)) {
  712.         case 0:                /* normal character */
  713.                 switch (state) {
  714.                     case 0:            /* normal */
  715.                             textlen++;
  716.                             break;
  717.                     case 1:            /* last char. diacritic */
  718.                             if (textlen > 1) {
  719.                                 DrawText(textptr, 0, textlen-1);
  720.                                 textptr += textlen-1;
  721.                                 }
  722.                             drawdc(*textptr, *sptr);
  723.                             movechr(-1);
  724.                             blankcount++;
  725.                             textptr = sptr;
  726.                             textlen = 1;
  727.                             state = 0;
  728.                             break;
  729.                     default:
  730.                             break;
  731.                     }
  732.                 break;
  733.         case 1:                /* blank */
  734.                 switch (state) {
  735.                     case 0:            /* pending blanks */
  736.                             if (blankcount == 0) {
  737.                                 textlen++;
  738.                                 }
  739.                             else {
  740.                                 DrawText(textptr, 0, textlen);
  741.                                 blankcount++;
  742.                                 movechr(blankcount);
  743.                                 blankcount = 0;
  744.                                 textptr = sptr + 1;
  745.                                 textlen = 0;
  746.                                 state = 0;
  747.                                 }
  748.                             break;
  749.                     case 1:            /* last char. diacritic */
  750.                             if (textlen > 1) {
  751.                                 DrawText(textptr, 0, textlen-1);
  752.                                 textptr += textlen-1;
  753.                                 }
  754.                             drawdc(*textptr, *sptr);
  755.                             blankcount++;
  756.                             textptr = sptr + 1;
  757.                             textlen = 0;
  758.                             state = 0;
  759.                             break;
  760.                     default:
  761.                             break;
  762.                     }
  763.                 break;
  764.         case 2:                /* diacritic */
  765.                 switch (state) {
  766.                     case 0:            /* normal */
  767.                     case 1:            /* last char. diacritic */
  768.                             textlen++;
  769.                             state = 1;
  770.                             break;
  771.                     default:
  772.                             break;
  773.                     }
  774.                 break;
  775.         default:
  776.                 break;
  777.         }
  778.     sptr++;
  779.     }
  780.     if (textlen > 0) {
  781.         DrawText(textptr, 0, textlen);
  782.         }
  783.     if (blankcount > 0) {
  784.         movechr(blankcount);
  785.         }
  786. }
  787.  
  788. short alatype(unsigned char *s)
  789. {
  790. register unsigned char c;
  791.  
  792. c = *s;
  793. if ((c == 0x40) || (c == 0x00)) return(1);        /* blank or null */
  794. if ((c%16) < 10) return(0);                        /* normal character */
  795. if (c < 0x80) return(0);
  796. if ((c >= 0xa0) && (c <= 0xbf)) return(0);
  797. if (c >= 0xf0) return(0);
  798. return(2);
  799. }
  800.  
  801. void movechr(short n)
  802. {
  803. FontInfo fi;
  804.  
  805. if (n == 0) return;
  806. GetFontInfo(&fi);
  807. Move(fi.widMax*n, 0);
  808. }
  809.  
  810. void drawdc(register unsigned char dc,
  811.             register unsigned char c)
  812.                     /* draw diacritic, adjusting postion depending on
  813.                        the character being modified */
  814. {
  815. register char adjflag;
  816. FontInfo fi;
  817.  
  818. adjflag = 0;
  819.                     /* check for lowercase character */
  820. if (c == 0x40) adjflag = 1;
  821. else if ((c >= 0x52) && (c <= 0x58)) adjflag = 1;
  822. else if ((c >= 0x81) && (c <= 0x85)) adjflag = 1;
  823. else if ((c >= 0x87) && (c <= 0x88)) adjflag = 1;
  824. else if ((c >= 0x94) && (c <= 0x99)) adjflag = 1;
  825. else if (c == 0xa2) adjflag = 1;
  826. else if ((c >= 0xa4) && (c <= 0xa9)) adjflag = 1;
  827. if (adjflag) {        /* check for upper diacritic */
  828.     if ((dc >= 0x8e) && (dc <= 0x8f)) adjflag = 0;
  829.     else if ((dc >= 0x9e) && (dc <= 0x9f)) adjflag = 0;
  830.     else if ((dc >= 0xca) && (dc <= 0xcc)) adjflag = 0;
  831.     else if (dc == 0xda) adjflag = 0;
  832.     else if ((dc >= 0xdc) && (dc <= 0xdd)) adjflag = 0;
  833.     else if (dc == 0xea) adjflag = 0;
  834.     else if (dc >= 0xec) adjflag = 0;
  835.     }
  836. if (adjflag) {
  837.     GetFontInfo(&fi);
  838.     Move(0, fi.ascent/6);    /* 1 for 9 pt., 2 for 12 pt. */
  839.     }
  840. DrawChar(dc);
  841. if (adjflag) Move(0, -(fi.ascent/6));
  842. }
  843.  
  844. void statline(cnr *cp)
  845. {
  846.  
  847. static unsigned char *days[] = {"Sun",
  848.                 "Mon",
  849.                 "Tue",
  850.                 "Wed",
  851.                 "Thu",
  852.                 "Fri",
  853.                 "Sat"
  854.                 };
  855. static unsigned char *months[] = {"Jan",
  856.                 "Feb",
  857.                 "Mar",
  858.                 "Apr",
  859.                 "May",
  860.                 "Jun",
  861.                 "Jul",
  862.                 "Aug",
  863.                 "Sep",
  864.                 "Oct",
  865.                 "Nov",
  866.                 "Dec"
  867.                 };
  868. DateTimeRec today;
  869. static unsigned long * Ticks = (unsigned long *)0x16a;
  870. unsigned char errmsg[16];
  871. char cpos;
  872. char klock, kcode;
  873. short vpos;
  874. RGBColor rgbtemp;
  875.  
  876. if ((((*Ticks) - cp->last_t) > 540) || (cp->last_stat_time != cp->cs.stat_time)) {
  877.     if (cp->cs.stat_time >= 8) cp->cs.stat_time -= 8;
  878.     cp->last_stat_time = cp->cs.stat_time;
  879.     if (cp->cs.stat_time > 0) {
  880.         GetTime(&today);
  881.         if (cp->cs.stat_time == 1) {
  882.             if (today.hour == 0) today.hour = 12;
  883.             if (today.hour > 12) today.hour -= 12;
  884.             }
  885.         sprintf(cp->statresult,"%s %02d %s %02d:%02d",
  886.             days[today.dayOfWeek-1],today.day,months[today.month-1],
  887.             today.hour,today.minute);
  888.         }
  889.     else strcpy(cp->statresult, "");
  890.     }
  891.  
  892. if (colormac && (!cp->cs.nocolor) && cp->drawpict) {
  893.     GetEntryColor(cp->myPalette, RGBback, &rgbtemp);
  894.     RGBBackColor(&rgbtemp);
  895.     }
  896. EraseRect(&(cp->statRect));
  897. TextFont(SYMBOLFONT);
  898. TextSize(12);
  899. if (colormac && (!cp->cs.nocolor)) {
  900.     GetEntryColor(cp->myPalette, RGBstat, &rgbtemp);
  901.     RGBForeColor(&rgbtemp);
  902.     }
  903. cpos = cp->cs.curpos;
  904. klock = cp->kblock;
  905. kcode = cp->kblcode;
  906. vpos = cp->vpixsize - 12;
  907. if (!klock) if (cp->wr_active) {
  908.     klock = 1;
  909.     kcode = 2;
  910.     }
  911. if (cp->logon) {
  912.     MoveTo(-2, vpos);
  913.     DrawChar(0x00);
  914.     }
  915. if (cp->online) {
  916.     MoveTo(7, vpos);
  917.     DrawChar(0x01);
  918.     }
  919. MoveTo(16, vpos);
  920. DrawChar(0x02);
  921. if (cp->insmode) {
  922.     MoveTo(290, vpos);
  923.     DrawChar(0x07);
  924.     }
  925. if (klock || (cp->vmxbgn && (!(cp->vmxsub)))) {
  926.     MoveTo(61, vpos);
  927.     DrawChar(0x03);
  928.     }
  929. if (klock && (kcode == 2)) {
  930.     MoveTo(74, vpos);
  931.     DrawChar(0x08);
  932.     }
  933. if (klock && (kcode == 3)) {
  934.     MoveTo(74, vpos);
  935.     DrawChar(0x09);
  936.     DrawChar(0x0a);
  937.     DrawChar(0x0b);
  938.     DrawChar(0x0c);
  939.     }
  940. if ((!klock) && (cp->kb_err == 1)) {
  941.     MoveTo(74, vpos);
  942.     DrawChar(0x05);
  943.     }
  944. if ((!klock) && (cp->kb_err == 2)) {
  945.     MoveTo(74, vpos);
  946.     DrawChar(0x04);
  947.     DrawChar(0x05);
  948.     DrawChar(0x06);
  949.     }
  950. if (cp->ioerror != 0) {
  951.     MoveTo(150, vpos);
  952.     DrawChar(0x09);
  953.     DrawChar(0x0a);
  954.     DrawChar(0x0b);
  955.     DrawChar(0x0c);
  956.     MoveTo(175, vpos+1);
  957.     DrawChar(0x01);
  958.     }
  959. if (cp->vmxbgn || ftpcopen || ftpdopen || ftplopen) {
  960.     cpos = 0;
  961.     MoveTo(315, vpos);
  962.     DrawChar(0x0e);
  963.     Move(-2, 0);
  964.     DrawChar(0x04);
  965.     DrawChar(0x06);
  966.     Move(-2, 0);
  967.     DrawChar(0x0e);
  968.     }
  969. if (klock && (kcode == 4)) {
  970.     TextFont(0);
  971.     TextSize(0);
  972.     MoveTo(74, vpos+1);
  973.     DrawString("\pSession");
  974.     }
  975. TextFont(1);
  976. TextSize(0);
  977. if (klock && (kcode == 1)) {
  978.     MoveTo(74, vpos+1);
  979.     DrawString("\pSYSTEM");
  980.     }
  981. if (klock && (kcode == 3)) {
  982.     MoveTo(112, vpos+1);
  983.     DrawString("\p590");
  984.     }
  985. if ((!klock) && (cp->kb_err == 1)) {
  986.     MoveTo(84, vpos);
  987.     DrawChar('>');
  988.     }
  989. if ((!klock) && (cp->kb_err == 3)) {
  990.     MoveTo(74, vpos+1);
  991.     DrawString("\p?+");
  992.     }
  993. if (cp->ioerror != 0) {
  994.     sprintf(errmsg,"%d",cp->ioerror);
  995.     MoveTo(188, vpos+1);
  996.     c2pstr(errmsg);
  997.     DrawString(errmsg);
  998.     p2cstr(errmsg);
  999.     }
  1000. if (cp->aplmode) {
  1001.     MoveTo(245, vpos+1);
  1002.     DrawString("\pAPL");
  1003.     }
  1004. if (cpos) {
  1005.     sprintf(errmsg,"%02d/%02d", cp->y+1, cp->x+1);
  1006.     MoveTo(cp->cposRect.left, vpos+1);
  1007.     c2pstr(errmsg);
  1008.     DrawString(errmsg);
  1009.     p2cstr(errmsg);
  1010.     }
  1011. MoveTo(cp->hpixsize-134, vpos+1);
  1012. c2pstr(cp->statresult);
  1013. DrawString(cp->statresult);
  1014. p2cstr(cp->statresult);
  1015. MoveTo(-4,cp->vpixsize-25);
  1016. LineTo(cp->hpixsize-4,cp->vpixsize-25);
  1017. TextFont(cp->stdfont);
  1018. TextSize(cp->cur_ptsize);
  1019. if (colormac && (!cp->cs.nocolor) && cp->drawpict) {
  1020.     if (cp->cs.invertbw) GetEntryColor(cp->myPalette, RGBwhite, &rgbtemp);
  1021.              else GetEntryColor(cp->myPalette, RGBblack, &rgbtemp);
  1022.     RGBBackColor(&rgbtemp);
  1023.     }
  1024. }
  1025.  
  1026. void newstat(cnr *cp)
  1027. {
  1028. GrafPtr gp;
  1029. BitMap * srcbits;
  1030.  
  1031. if (sw_bgrnd) {
  1032.     sw_upd = 1;
  1033.     return;
  1034.     }
  1035. if (cp->myWindow == 0) return;
  1036.  
  1037. if (!(cp->textmap)) {                /* no screen buffer */
  1038.     GetPort(&gp);
  1039.     SetPort(cp->myWindow);
  1040.     statline(cp);
  1041.     /* ValidRect(&statRect); */    /* May need new grow icon */
  1042.     SetPort(gp);
  1043.     }
  1044. else {                            /* have screen buffer */
  1045.     GetPort(&gp);
  1046.     SetPort(cp->WritePtr);
  1047.     setgdev(cp);
  1048.     statline(cp);
  1049.     resetgdev();
  1050.     SetPort(cp->myWindow);
  1051.     if (colormac && (!cp->cs.nocolor)) {
  1052.         RGBForeColor(&realblack);
  1053.         RGBBackColor(&realwhite);
  1054.         srcbits = (BitMap *)(*(PixMapHandle)cp->WritePort.portBits.baseAddr);
  1055.         }
  1056.     else {
  1057.         srcbits = &(cp->WritePort.portBits);
  1058.         }
  1059.     if (cp->statcpos) {
  1060.         CopyBits(srcbits, &((cp->myWindow)->portBits),
  1061.             &(cp->cposRect), &(cp->cposRect), srcCopy, 0L);
  1062.         }
  1063.     else {
  1064.         CopyBits(srcbits, &((cp->myWindow)->portBits),
  1065.             &(cp->statRect), &(cp->statRect), srcCopy, 0L);
  1066.         }
  1067.     /* ValidRect(&statRect); */    /* may need new grow icon */
  1068.     SetPort(gp);
  1069.     }
  1070. }
  1071.  
  1072. void beep(cnr *cp)
  1073. {
  1074. static short duration = 3;
  1075. static short sw_dur = 2;
  1076. OSErr rc;
  1077.  
  1078. if (cp != 0) {
  1079.     if (cp->apiopen) {
  1080.         if (cp->apihide) return;
  1081.         }
  1082.     }
  1083.  
  1084. if (sw_bgrnd) sw_beep = 1;
  1085.  
  1086. if (cp != 0) {
  1087.     rc = mybeep(cp);
  1088.     if (rc == 0) return;
  1089.     }
  1090.     
  1091. if (sw_bgrnd || mf_bgrnd) {
  1092.     SysBeep(sw_dur);
  1093.     SysBeep(sw_dur);
  1094.     }
  1095. else SysBeep(duration);
  1096. }
  1097.  
  1098. OSErr mybeep(cnr *cp)
  1099. {
  1100. OSErr rc, playrc;
  1101. SndChannelPtr default_scp;
  1102. SndCommand endcmd;
  1103.  
  1104. if (cp->sndhandle == 0) return(1);
  1105.  
  1106. if (sndactive) {
  1107.     SndDisposeChannel(scp, true);
  1108.     sndactive = 0;
  1109.     }
  1110.  
  1111. if (mf_bgrnd || sw_bgrnd) {        /* play sound synchronously */
  1112.     default_scp = 0;
  1113.     rc = SndNewChannel(&default_scp, 0, 0L, 0L);
  1114.     if (rc == noErr) {
  1115.         playrc = SndPlay(default_scp, cp->sndhandle, 0);
  1116.         rc = SndDisposeChannel(default_scp, 0);
  1117.         if (playrc == noErr) return(rc);
  1118.         else return(playrc);        
  1119.         }
  1120.     else {
  1121.         return(rc);
  1122.         }
  1123.     }
  1124.  
  1125. rc = SndNewChannel(&scp, 0, 0L, (SndCallBackProcPtr)sndproc);
  1126. if (rc != noErr) return(rc);
  1127. rc = SndPlay(scp, cp->sndhandle, true);
  1128. if (rc != noErr) {
  1129.     SndDisposeChannel(scp, true);
  1130.     return(rc);
  1131.     }
  1132. sndactive = 1;
  1133. endcmd.cmd = callBackCmd;
  1134. endcmd.param1 = 0;
  1135. endcmd.param2 = GetA5();
  1136. rc = SndDoCommand(scp, &endcmd, true);
  1137. if (rc != noErr) {
  1138.     SndDisposeChannel(scp, true);
  1139.     sndactive = 0;
  1140.     }
  1141. return(rc);
  1142. }
  1143.  
  1144. void sndend(void)
  1145. {
  1146. if (sndactive == 1) sndactive = 2;        /* indicate dispose call needed */
  1147. }
  1148.  
  1149. void drawcurs(char restore, cnr *cp)    /* draw cursor in screen window */
  1150. {
  1151. RGBColor rgbchar, mywhite, myblack, myback;
  1152. unsigned short foffset, fattr, cattr;
  1153. unsigned char attrbits, trim;
  1154. short start, end, count, lend;
  1155. static unsigned char * hiliteMode = (unsigned char *)0x938;
  1156.  
  1157.                     /* invert rectangle if no color or unknown color */
  1158. if (((!colormac) || (cp->cs.nocolor)) || cp->drawpict) {
  1159.     InvertRect(&(cp->er));
  1160.     return;
  1161.     }
  1162.  
  1163.                         /* get colors we will need */
  1164. GetEntryColor(cp->myPalette, RGBwhite, &mywhite);
  1165. GetEntryColor(cp->myPalette, RGBblack, &myblack);
  1166. GetEntryColor(cp->myPalette, RGBback, &myback);
  1167.  
  1168. if (!restore) {            /* compute background if not restore call */
  1169.                                     /* define attrbits and trim */
  1170.     foffset = getattr(cp->curadr, cp);
  1171.     fattr = (cp->atrbuff)[foffset];
  1172.     cattr = (cp->atrbuff)[cp->curadr];
  1173.     trim = 1;
  1174.     getdspatr(&attrbits, &trim, &rgbchar, cattr, fattr, cp);
  1175.     if (!(fattr & 0x2000)) trim = 0;    /* unprotected not trimmed */
  1176.     if (cattr & 0x8000) {                /* handle attribute byte */
  1177.         attrbits = cp->cs.attrmap[6];
  1178.         trim = 0;
  1179.         }
  1180.                                     /* determine background color */
  1181.                                         /* reversed or underline cursor & field */
  1182.     if ((attrbits & 0x20) || ((attrbits & 0x10) && (!(cp->cs.blockcurs)))) {
  1183.         if (trim) {
  1184.             start = (cp->curadr/cp->scrhsize) * cp->scrhsize;
  1185.             lend = start + cp->scrhoff;
  1186.             if ((foffset >= start) && (foffset < cp->curadr))
  1187.                 start = foffset+1;
  1188.             end = start;
  1189.             while (end < lend) {
  1190.                 end++;
  1191.                 if ((cp->atrbuff)[end] & 0x8000) {
  1192.                     end--;
  1193.                     break;
  1194.                     }
  1195.                 }
  1196.             count = end - start + 1;
  1197.             calctrim(&start, &count, cp);
  1198.             end = start + count - 1;
  1199.             if ((count > 0) && (cp->curadr >= start) && (cp->curadr <= end)) trim = 0;
  1200.             }
  1201.         if (trim) cp->rgbbk = myback;    /* trim actually applies where cursor is */
  1202.         else if (((attrbits & 0x30) == 0x30) && (!(cp->cs.blockcurs))) {
  1203.                                         /* reverse & underline & underline cursor */
  1204.                     if (cp->cs.invertbw) cp->rgbbk = mywhite;
  1205.                     else cp->rgbbk = myblack;
  1206.                     }
  1207.              else cp->rgbbk = rgbchar;        /* reverse | underline & underline cursor */
  1208.         }
  1209.     else cp->rgbbk = myback;                /* normal */
  1210.     }
  1211.                             /* hilight (or unhilight) cursor rectangle */
  1212. if (cp->cs.invertbw) {
  1213.     HiliteColor(&myblack);
  1214.     RGBBackColor(&(cp->rgbbk));
  1215.     }
  1216. else {
  1217.     RGBBackColor(&mywhite);
  1218.     HiliteColor(&(cp->rgbbk));
  1219.     }
  1220. (*hiliteMode) &= 0x7f;
  1221. InvertRect(&(cp->er));
  1222.                             /* restore what we changed */
  1223. HiliteColor(&realblack);
  1224. if (cp->textmap) RGBBackColor(&realwhite);
  1225. else RGBBackColor(&myback);
  1226. }
  1227.  
  1228. void defcursor(short cx, short cy, cnr *cp)
  1229. {
  1230. cp->er.left = cx * cp->htxtsize;
  1231. cp->er.top = cy * cp->vtxtsize;
  1232. cp->er.right = cp->er.left + cp->curhsize;
  1233. cp->er.bottom = cp->er.top + cp->curvsize;
  1234. if (cp->cs.blockcurs) return;
  1235. cp->er.bottom -= (cp->curvsize>>2) - 1;
  1236. cp->er.top = cp->er.bottom - 1;
  1237. }
  1238.  
  1239. void justGrowIcon(char rgnok, cnr *cp)
  1240. {
  1241. GrafPtr psave;
  1242. RGBColor myback, mystat, actback, actstat;
  1243. Rect temprect;
  1244.  
  1245. GetPort(&psave);
  1246. SetPort(cp->myWindow);
  1247. if (!rgnok) SetClip(cp->cliprgn);
  1248.  
  1249. if (colormac && (!cp->cs.nocolor)) {
  1250.     GetEntryColor(cp->myPalette, RGBback, &myback);
  1251.     GetEntryColor(cp->myPalette, RGBstat, &mystat);
  1252.     actualcolor(&myback, &actback, cp);
  1253.     actualcolor(&mystat, &actstat, cp);
  1254.     if (actback == actstat) InvertColor(&mystat);
  1255.     RGBForeColor(&mystat);
  1256.     if (cp->textmap) RGBBackColor(&myback);
  1257.     }
  1258.  
  1259. temprect = (cp->myWindow)->portRect;
  1260. temprect.top = temprect.bottom-15;
  1261. temprect.left = temprect.right-15;
  1262. EraseRect(&temprect);
  1263. MoveTo(temprect.left, temprect.bottom);
  1264. LineTo(temprect.left, temprect.top);
  1265. LineTo(temprect.right, temprect.top);
  1266. if (((WindowPeek)cp->myWindow)->hilited) {
  1267.     temprect.left += 3;
  1268.     temprect.right = temprect.left + 7;
  1269.     temprect.top += 3;
  1270.     temprect.bottom = temprect.top + 7;
  1271.     FrameRect(&temprect);
  1272.     MoveTo(temprect.right, temprect.bottom-5);
  1273.     Line(3, 0);
  1274.     Line(0, 8);
  1275.     Line(-8, 0);
  1276.     Line(0, -3);
  1277.     }
  1278. if (colormac && (!cp->cs.nocolor) && cp->textmap) RGBBackColor(&realwhite);
  1279.  
  1280. if (!rgnok) SetClip(cp->destrgn);
  1281.  
  1282. SetPort(psave);
  1283. }
  1284.  
  1285. void xfGrowIcon(cnr *cp)
  1286. {
  1287. GrafPtr psave;
  1288. Rect temprect;
  1289.  
  1290. GetPort(&psave);
  1291. SetPort(cp->xdlgptr);
  1292.  
  1293. temprect = (cp->xdlgptr)->portRect;
  1294. temprect.top = temprect.bottom-15;
  1295. temprect.left = temprect.right-15;
  1296. EraseRect(&temprect);
  1297. MoveTo(temprect.left, temprect.bottom);
  1298. LineTo(temprect.left, temprect.top);
  1299. LineTo(temprect.right, temprect.top);
  1300. if (((WindowPeek)cp->xdlgptr)->hilited) {
  1301.     temprect.left += 3;
  1302.     temprect.right = temprect.left + 7;
  1303.     temprect.top += 3;
  1304.     temprect.bottom = temprect.top + 7;
  1305.     FrameRect(&temprect);
  1306.     MoveTo(temprect.right, temprect.bottom-5);
  1307.     Line(3, 0);
  1308.     Line(0, 8);
  1309.     Line(-8, 0);
  1310.     Line(0, -3);
  1311.     }
  1312. SetPort(psave);
  1313. }
  1314.  
  1315. void InitClip(cnr *cp)
  1316. {
  1317. ClipRect(&((cp->myWindow)->portRect));
  1318. GetClip(cp->cliprgn);
  1319. cp->gr_rect = (cp->myWindow)->portRect;
  1320. cp->gr_rect.top = cp->gr_rect.bottom-15;
  1321. cp->gr_rect.left = cp->gr_rect.right-15;
  1322. RectRgn(temprgn, &(cp->gr_rect));
  1323. DiffRgn(cp->cliprgn, temprgn, cp->destrgn);
  1324. SetClip(cp->destrgn);
  1325. }
  1326.  
  1327. void mousesel(short function, short location, char doubleflag, cnr *cp)
  1328. {
  1329. short toploc, bottomloc;
  1330. short startcol, toprow, endcol, bottomrow, t;
  1331. short scrtop, scrbottom, scrtop2, scrbottom2;
  1332. short scrstart, scrend, scrleft, scrright;
  1333.  
  1334. switch(function) {
  1335.     case 0:                    /* initialization */
  1336.                 cp->init_loc = location;
  1337.                 cp->showsel = 0;
  1338.                 break;
  1339.     case 1:                    /* display call */
  1340.     case 2:
  1341.                 if (location != cp->init_loc) {
  1342.                     if (cp->showsel) {
  1343.                         if (location == cp->sel_loc) break;
  1344.                         invsel(&(cp->lastsel), cp);
  1345.                         }
  1346.                         /* define lastsel */
  1347.                     toploc = cp->init_loc;
  1348.                     bottomloc = location;
  1349.                     if (toploc > bottomloc) {
  1350.                         toploc = location;
  1351.                         bottomloc = cp->init_loc;
  1352.                         }
  1353.                     if (function == 2) {
  1354.                         bottomloc--;
  1355.                         if (doubleflag) wordadj(&toploc, &bottomloc, 0, cp);
  1356.                         }
  1357.                     startcol = toploc % cp->scrhsize;
  1358.                     endcol = bottomloc % cp->scrhsize;
  1359.                     toprow = toploc / cp->scrhsize;
  1360.                     bottomrow = bottomloc / cp->scrhsize;
  1361.                     if ((function == 1) && (startcol > endcol)) {
  1362.                         t = startcol;
  1363.                         startcol = endcol;
  1364.                         endcol = t;
  1365.                         }
  1366.                     scrtop = toprow * cp->vtxtsize + cp->htxtstrt - 1;
  1367.                     scrbottom2 = bottomrow * cp->vtxtsize + cp->htxtstrt - 1;
  1368.                     scrtop2 = (toprow+1) * cp->vtxtsize + cp->htxtstrt -1;
  1369.                     scrbottom  = (bottomrow+1) * cp->vtxtsize + cp->htxtstrt -1;
  1370.                     scrstart = startcol * cp->htxtsize;
  1371.                     scrleft = 0;
  1372.                     scrend = (endcol+1) * cp->htxtsize + 1;
  1373.                     scrright = cp->scrhsize * cp->htxtsize + 1;
  1374.                     if ((function == 1) ||
  1375.                         ((startcol == 0) && (endcol == cp->scrhoff)) ||
  1376.                         (toprow == bottomrow)) {
  1377.                         cp->lastsel.x1 = cp->lastsel.x2 =
  1378.                             cp->lastsel.x3 = cp->lastsel.x8 = scrstart;
  1379.                         cp->lastsel.x4 = cp->lastsel.x5 =
  1380.                             cp->lastsel.x6 = cp->lastsel.x7 = scrend;
  1381.                         cp->lastsel.y1 = cp->lastsel.y2 =
  1382.                             cp->lastsel.y3 = cp->lastsel.y4 = scrtop;
  1383.                         cp->lastsel.y5 = cp->lastsel.y6 =
  1384.                             cp->lastsel.y7 = cp->lastsel.y8 = scrbottom;
  1385.                         }
  1386.                     else {
  1387.                         cp->lastsel.x1 = scrleft;
  1388.                         cp->lastsel.y1 = scrtop2;
  1389.                         cp->lastsel.x2 = scrstart;
  1390.                         cp->lastsel.y2 = scrtop2;
  1391.                         cp->lastsel.x3 = scrstart;
  1392.                         cp->lastsel.y3 = scrtop;
  1393.                         cp->lastsel.x4 = scrright;
  1394.                         cp->lastsel.y4 = scrtop;
  1395.                         cp->lastsel.x5 = scrright;
  1396.                         cp->lastsel.y5 = scrbottom2;
  1397.                         cp->lastsel.x6 = scrend;
  1398.                         cp->lastsel.y6 = scrbottom2;
  1399.                         cp->lastsel.x7 = scrend;
  1400.                         cp->lastsel.y7 = scrbottom;
  1401.                         cp->lastsel.x8 = scrleft;
  1402.                         cp->lastsel.y8 = scrbottom;
  1403.                         if (startcol == 0) {
  1404.                             cp->lastsel.x2 = cp->lastsel.x3 = cp->lastsel.x1;
  1405.                             cp->lastsel.y1 = cp->lastsel.y2 = cp->lastsel.y3;
  1406.                             }
  1407.                         if (endcol == cp->scrhoff) {
  1408.                             cp->lastsel.x6 = cp->lastsel.x7 = cp->lastsel.x5;
  1409.                             cp->lastsel.y5 = cp->lastsel.y6 = cp->lastsel.y7;
  1410.                             }
  1411.                         }
  1412.                     invsel(&(cp->lastsel), cp);
  1413.                     cp->showsel = 1;
  1414.                     cp->sel_loc = location;
  1415.                     break;
  1416.                     }            
  1417.                 if (cp->showsel == 0) break;
  1418.                 invsel(&(cp->lastsel), cp);
  1419.                 cp->showsel = 0;
  1420.                 break;
  1421.     case 3:                    /* termination */
  1422.                 if (cp->showsel == 0) break;
  1423.                 invsel(&(cp->lastsel), cp);
  1424.                 cp->showsel = 0;
  1425.                 break;
  1426.     default:
  1427.                 break;
  1428.     }    
  1429. }
  1430.  
  1431. void invsel(selcoord *r, cnr *cp)
  1432. {
  1433. PenState ps;
  1434. GrafPtr gp;
  1435. static Pattern gray =
  1436.     {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
  1437. selcoord s;
  1438.  
  1439. s = *r;
  1440. GetPort(&gp);
  1441. SetPort(cp->myWindow);
  1442. GetPenState(&ps);
  1443. PenPat(&gray);
  1444. PenMode(patXor);
  1445. MoveTo(s.x1, s.y1);
  1446. if ((s.x2 != s.x1) || (s.y2 != s.y1)) {
  1447.     if ((s.y1 == s.y6) && (s.x6 < s.x2)) {
  1448.         LineTo(s.x6, s.y6);
  1449.         MoveTo(s.x2, s.y2);
  1450.         }
  1451.     else LineTo(s.x2, s.y2);
  1452.     }
  1453. if ((s.x3 != s.x2) || (s.y3 != s.y2)) LineTo(s.x3, s.y3);
  1454. LineTo(s.x4, s.y4);
  1455. LineTo(s.x5, s.y5);
  1456. if ((s.x6 != s.x5) || (s.y6 != s.y5)) {
  1457.     if ((s.y1 == s.y6) && (s.x6 < s.x2)) {
  1458.         LineTo(s.x2, s.y2);
  1459.         MoveTo(s.x6, s.y6);
  1460.         }
  1461.     else LineTo(s.x6, s.y6);
  1462.     }
  1463. if ((s.x7 != s.x6) || (s.y7 != s.y6)) LineTo(s.x7, s.y7);
  1464. LineTo(s.x8, s.y8);
  1465. LineTo(s.x1, s.y1);
  1466. SetPenState(&ps);
  1467. SetPort(gp);
  1468. }
  1469.